package cn.ali.mybatis.plugin;

import cn.ali.bean.PageVo;
import cn.ali.page.PageResult;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;


/**
 * Executor：拦截执行器的方法。
 * ParameterHandler：拦截参数的处理。
 * ResultHandler：拦截结果集的处理。
 * StatementHandler：拦截Sql语法构建的处理。
 */
@Intercepts({
        @Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class,Integer.class})
})
public class PqsStatementPlugin implements Interceptor {


    public <T> T realTarget(Object target) {
        if (Proxy.isProxyClass(target.getClass())) {
            MetaObject metaObject = SystemMetaObject.forObject(target);
            return realTarget(metaObject.getValue("h.target"));
        }
        return (T) target;
    }

    /**
     * 执行目标方法
     *
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("[StatementHandler prepare 方法]mybatis 自动以拦截器的 intercept");
        StatementHandler statementHandler = (StatementHandler) this.realTarget(invocation.getTarget());
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();
        System.out.println("[StatementHandler prepare 方法]mybatis 自动以拦截器的 sql:"+sql);

//        Field sqlField = boundSql.getClass().getDeclaredField("sql");
//        sqlField.setAccessible(true);
//        sql = sql + " and 1=1";
//        sqlField.set(boundSql, sql);
//        String newSql = boundSql.getSql();

        return invocation.proceed();

    }

    public static String concatOrderBy(String originalSql, PageVo page) {


        return originalSql;
    }


    /**
     * 对目标对象进行包装,返回一个代理对象
     *
     * @param target
     * @return
     */
    @Override
    public Object plugin(Object target) {
        Object wrap = Plugin.wrap(target, this);
        return wrap;
    }

}
